<cfcomponent name="User" hint="User is an account of the most generic kind for this system.&nbsp; It is the central entity for security audits." extends="com.revenea.root.Object">


	<!--- ORM --->

	<!---<cfxml variable="variables.instance.xmlORM">
		<mapping>
			<class name="revenea.account.data.User" table="users">
				<id name="id" column="user_id" type="numeric">
					<generator class="increment" />
				</id>
				<property name="username" column="username" type="string">
					<accessor type="set" generate="true" access="public" />
					<accessor type="get" generate="true" access="public" />
				</property>
				<property name="isAuthenticated" type="boolean">
					<accessor type="set" generate="true" access="private" />
					<accessor type="get" generate="true" access="public" />
				</property>
				<one-to-one name="person" class="revenea.organization.data.Person" constrained="true" />
			</class>
		</mapping>
	</cfxml>--->


	<!--- Accessors --->


	<cffunction name="setUsername" access="public" returntype="void" output="false">
		<cfargument name="username" type="string" required="true" />
		<cfset variables.instance.username = arguments.username />
		<cfset this.username = arguments.username />
	</cffunction>
	<cffunction name="getUsername" access="public" returntype="string" output="false">
		<cfreturn variables.instance.username />
	</cffunction>

	<cffunction name="setIsAuthenticated" access="public" returntype="void" output="false">
		<cfargument name="isAuthenticated" type="boolean" required="true" />
		<cfset variables.instance.isAuthenticated = arguments.isAuthenticated />
		<cfset this.isAuthenticated = arguments.isAuthenticated />
	</cffunction>
	<cffunction name="getIsAuthenticated" access="public" returntype="boolean" output="false">
		<cfreturn variables.instance.isAuthenticated />
	</cffunction>

	<cffunction name="setPerson" access="public" returntype="void" output="false">
		<cfargument name="oPerson" type="revenea.organization.data.Person" required="true" />
		<cfset variables.instance.person = arguments.oPerson />
	</cffunction>
	<cffunction name="getPerson" access="public" returntype="revenea.organization.data.Person" output="false">
		<cfif (NOT IsDefined("variables.instance.person"))>
			<cfset variables.instance.person = CreateObject("component", "revenea.organization.data.Person").init(variables.instance.personId) />
		</cfif>
		<cfreturn variables.instance.person />
	</cffunction>


	<!--- Public methods --->


	<cffunction name="authenticate" returnType="boolean" access="public" output="false" hint="Required that the User is loaded.&nbsp; Will return a success/fail boolean telling if authentication against the directory/data store was successful.&nbsp; Sets the isAuthenticated property of User.">
		<cfargument name="sPassword" type="string" required="true" />
		<cfset var local = StructNew() />
		<cfscript>
			local.qAuthMatches = getDAO().authenticate(this, arguments.sPassword);
			if (local.qAuthMatches.recordCount EQ 1)
			{
				setIsAuthenticated(true);
				return true;
			}
			else
			{
				return false;
			}
		</cfscript>
	</cffunction>

	<cffunction name="changePassword" returntype="boolean" access="public" output="false" hint="Provides the application with an interface for a User to change their OWN password.  This is NOT the method for use by an administrative utility for setting / resetting passwords.">
		<cfargument name="sOldPassword" type="string" required="true" hint="The old password.  Must be able to authenticate with this." />
		<cfargument name="sNewPassword" type="string" required="true" hint="The new password that will replace the old one." />
		<cfset var local = StructNew() />
		<cfif (NOT authenticate(arguments.sOldPassword))>
			<cfreturn false />
		<cfelse>
			<cfset local.blnSuccess = getDAO().setPassword(this, arguments.sNewPassword) />
			<!--- TODO: Add auditing hooks here --->
			<cfreturn local.blnSuccess />
		</cfif>
	</cffunction>


	<!--- Private methods --->


	<cffunction name="populate" returnType="void" access="private" output="false" hint="Populate this entity's properties based on the provided record set.&nbsp; Population is accomplished internally, by reference, so nothing is returned.">
		<cfargument name="qSource" type="query" required="true" hint="Record set provided with which to populate the entity." />
		<cfscript>
			// Zero everything out before assigning values
			setDefaults();
			// Allow the superclass to populate first
			super.populate(qSource);
			// Set properties
			// Use setters for those with accessors
			setId(arguments.qSource.user_id);
			setUsername(arguments.qSource.username);
			// Assign directly to the relational properties
			variables.instance.personId = arguments.qSource.person_id;
		</cfscript>
	</cffunction>

	<cffunction name="setDefaults" returnType="void" access="private" output="false" hint="Sets all properties with accepted default values">
		<cfscript>
			// Ask the super class to default values first
			super.setDefaults();
			// Set default values
			setUsername("");
			setIsAuthenticated(false);
			// Set private properties
			variables.instance.personId = 0;
			// Destroy any previously cached entities
			structDelete(variables.instance, "person");
		</cfscript>
	</cffunction>


</cfcomponent>